package netty.tcp.websocket;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import lombok.extern.slf4j.Slf4j;

import java.util.Objects;

/**
 * @author god.yang
 * websocket推送数据,数据data的最后一道关卡
 */
@Slf4j
@ChannelHandler.Sharable
public class MessageOutHandler extends ChannelOutboundHandlerAdapter {
    @Override
    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) {
        // 传输了空数据,不执行
        if (Objects.isNull(msg)) {
            return;
        }

        this.handleOutMessage(ctx, msg);
    }

    /**
     * 处理消息输出
     */
    private void handleOutMessage(ChannelHandlerContext ctx, Object msg) {
        // MessageContainer
        if (msg instanceof MessageContainer messageContainer) {
            ChannelFuture channelFuture = writeString(ctx, messageContainer.getJsonByte());

            channelFuture.addListener(future -> {
                if (future.isSuccess()) {
                } else {
                    log.error("merged msg send to ELB failed, channelId: {}", ctx.channel().id().asLongText(), future.cause());
                }
                if (future.isDone()) {
                }
                if (future.isCancelled()) {
                }
            });

            return;
        }

        // 首次建链会有FullHttpResponse
        if (msg instanceof FullHttpResponse) {
            ctx.writeAndFlush(msg);
            return;
        }

    }

    /**
     * 文本传输
     */
    private ChannelFuture writeString(ChannelHandlerContext ctx, ByteBuf byteBuf) {
        TextWebSocketFrame textWF = new TextWebSocketFrame(byteBuf);
        return ctx.write(textWF);
    }

    /**
     * 文本传输
     */
    private ChannelFuture writeString(ChannelHandlerContext ctx, String msg) {
        TextWebSocketFrame textWF = new TextWebSocketFrame(msg);
        return ctx.write(textWF);
    }

    /**
     * binary传输
     */
    private void writeBytes(ChannelHandlerContext ctx, byte[] src) {
        BinaryWebSocketFrame binaryWF = new BinaryWebSocketFrame(Unpooled.wrappedBuffer(src));
        ctx.writeAndFlush(binaryWF);
    }
}
